﻿using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using XNAGuiLib.GuiLibButtons;
using XNAGuiLib.GuiLibAction;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
using XNAGuiLib.GuiLibResourceManager;

namespace XNAGuiLib.GuiLibScrollbar
{
    public abstract class ScrollbarObject : InterfaceObject, IScrollbar
    {

        #region Field - ScrollTarget
        protected IScrollable _scrollTarget;
        /// <summary>
        /// gets or sets the IScroll target to invoke the DoScroll()-method on
        /// </summary>
        public IScrollable ScrollTarget
        {
            get
            {
                return _scrollTarget;
            }
            set
            {
                _scrollTarget = value;
            }
        }
        #endregion

        #region Field - ScrollSteps
        private int _scrollSteps = 0;
        /// <summary>
        /// gets or sets the scroll Steps for this Scrollbar
        /// </summary>
        public int ScrollSteps
        {
            get
            {
                return _scrollSteps;
            }
            set
            {
                _scrollSteps = value;
                RefreshScrollBar();
            }
        }
        #endregion

        #region Field - BlockOnStep
        private int _blockOnStep = 0;
        /// <summary>
        /// gets or sets the scroll Steps for this Scrollbar
        /// </summary>
        public int BlockOnStep
        {
            get
            {
                return _blockOnStep;
            }
            set
            {
                _blockOnStep = value;
            }
        }
        #endregion

        #region Field - BackgroundTexture
        protected TextureObject Background;
        #endregion

        #region Fields - ButtonObjects Scroll[...]
        protected ButtonObject ScrollUp;
        protected ButtonObject ScrollDown;
        protected ButtonObject ScrollBlock;
        #endregion


        #region Constructor - ScrollbarObject(Game game, string name, Vector2 relPosition, Vector2 bounds, Color fontColor, RManager.RManagerType styleType)
        public ScrollbarObject(Game game, string name, Vector2 relPosition, Vector2 bounds, Color fontColor, GuiResourceManager.ResourceManagerType styleType)
            : base(game, name, relPosition, true)
        {
            // initializing the resourceContentManager for default style 
            // (this will be changed in 'styled' TextfieldObject classes)
            ResourceContentManager rcm = GuiResourceManager.Instance(this.Game, styleType);
            // ResourceContentManager rcm = RManager.Instance(this.Game).StyleHorizonsManager;

            // set the ScrollbarObjects bounds
            #region Init - Base Fields
            _bounds = bounds;
            #endregion
            // set (up) the Scrollbar background
            #region Init - Background
            Background = new TextureObject(rcm.Load<Texture2D>("scrl_bg"), "scroll_bg", Statics.ZeroVector2, _bounds, true);
            this.Add(Background);
            #endregion
            // set (up) the ScrollUp component
            #region Init - ScrollUp
            ScrollUp = new DefaultButton(game, "scrollUp", Statics.ZeroVector2, new Vector2(_bounds.X, 10.0f), "-", ButtonObject.ButtonObjectState.Unclicked, ButtonObject.ButtonSize.BS017x017);
            ScrollUp.Clicked = new TextureObject(rcm.Load<Texture2D>("scrl_clicked_sm"), "scrollUp_clicked", Statics.ZeroVector2, Statics.ZeroVector2);
            ScrollUp.Unclicked = new TextureObject(rcm.Load<Texture2D>("scrl_unclicked_sm"), "scrollUp_unclicked", Statics.ZeroVector2, Statics.ZeroVector2);
            ScrollUp.Hover = new TextureObject(rcm.Load<Texture2D>("scrl_hover_sm"), "scrollUp_hover", Statics.ZeroVector2, Statics.ZeroVector2);
            ScrollUp.TextColor = fontColor;
            ScrollUp.Bounds = new Vector2(_bounds.X, ScrollUp.Unclicked.Texture.Height);
            this.Add(ScrollUp);
            #endregion 
            // set (up) the ScrollDown component
            #region Init - ScrollDown
            ScrollDown = new DefaultButton(game, "scrollDown", Statics.ZeroVector2, new Vector2(_bounds.X, 10.0f), "+", ButtonObject.ButtonObjectState.Unclicked, ButtonObject.ButtonSize.BS017x017);
            ScrollDown.Clicked = new TextureObject(rcm.Load<Texture2D>("scrl_clicked_sm"), "scrollDown_clicked", Statics.ZeroVector2, Statics.ZeroVector2);
            ScrollDown.Unclicked = new TextureObject(rcm.Load<Texture2D>("scrl_unclicked_sm"), "scrollDown_unclicked", Statics.ZeroVector2, Statics.ZeroVector2);
            ScrollDown.Hover = new TextureObject(rcm.Load<Texture2D>("scrl_hover_sm"), "scrollDown_hover", Statics.ZeroVector2, Statics.ZeroVector2);
            ScrollDown.TextColor = fontColor;
            ScrollDown.Bounds = new Vector2(_bounds.X, ScrollDown.Unclicked.Texture.Height);
            this.Add(ScrollDown);
            #endregion
            // set (up) the ScrollBlock component
            #region Init - ScrollBlock
            ScrollBlock = new DefaultButton(game, "scrollUp", Statics.ZeroVector2, new Vector2(_bounds.X, 10.0f), "", ButtonObject.ButtonObjectState.Unclicked, ButtonObject.ButtonSize.BS017x017);
            ScrollBlock.Clicked = new TextureObject(rcm.Load<Texture2D>("scrl_unclicked"), "scrollBlock_unclicked", Statics.ZeroVector2, Statics.ZeroVector2);
            ScrollBlock.Unclicked = new TextureObject(rcm.Load<Texture2D>("scrl_unclicked"), "scrollBlock_unclicked", Statics.ZeroVector2, Statics.ZeroVector2);
            ScrollBlock.Hover = new TextureObject(rcm.Load<Texture2D>("scrl_unclicked"), "scrollBlock_unclicked", Statics.ZeroVector2, Statics.ZeroVector2);
            ScrollBlock.TextColor = fontColor;

            this.Add(ScrollBlock);
            #endregion

            RefreshScrollBar();

            // set (up) the Actio for he scrollbar
            #region Init - Actions
            this.InstallAction(ActionFactory.InterfaceObjectAction(this, ScrollUp, Action.CommandType.Custom, MouseAction.Inputs.MouseButtonPressed,
            MouseAction.MouseButtons.Left, "scrollUp", Action.KeyModifiers.None));

            this.InstallAction(ActionFactory.InterfaceObjectAction(this, ScrollDown, Action.CommandType.Custom, MouseAction.Inputs.MouseButtonPressed,
                    MouseAction.MouseButtons.Left, "scrollDown", Action.KeyModifiers.None));
            #endregion
        }
        #endregion


        #region Method - RefreshScrollBar()
        public void RefreshScrollBar()
        {
            // calculates scrollBlock maximum height (if there are no scrollsteps possible
            int scrollBlock_maxheight = (int)(_bounds.Y - ScrollDown.Height - ScrollUp.Height);
            int scrollBlock_height = scrollBlock_maxheight / (_scrollSteps + 1);

            Background.RelativePosition = _relativePosition;
            ScrollUp.RelativePosition = _relativePosition;

            ScrollBlock.RelativePosition = new Vector2(_relativePosition.X, _relativePosition.Y + ScrollUp.Height);
            // ScrollBlock.Y += ScrollUp.Height;
            ScrollBlock.Height = scrollBlock_height;
            ScrollDown.RelativePosition = _relativePosition;
            ScrollDown.Y = _relativePosition.Y + _bounds.Y - ScrollDown.Height;
        }
        #endregion

        #region Override Method - Rescale(Vector2 bounds)
        public override void Rescale(Vector2 bounds)
        {
            // (re)set bounds
            _bounds = bounds;
            // Rescale / Reposition Background
            this.TextureObject(this._textureObjs.IndexOf(this.Background)).Bounds = _bounds;
            this.TextureObject(this._textureObjs.IndexOf(this.Background)).RelativePosition = new Vector2(this.X, 0);
            // Rescale / Reposition ScrollUp
            this.ScrollUp.Rescale(new Vector2(_bounds.X, this.ScrollUp.Height));
            this.ScrollUp.RelativePosition = new Vector2(this.RelativePosition.X, 0);
            // Rescale / Reposition ScrollDown
            this.ScrollDown.Rescale(new Vector2(_bounds.X, this.ScrollUp.Height));
            this.ScrollDown.RelativePosition = new Vector2(this.RelativePosition.X, this.RelativePosition.Y + _bounds.Y - this.ScrollDown.Height);
            // Rescale / Reposition ScrollBlock
            this.ScrollBlock.Rescale(new Vector2(_bounds.X, this.Height - (ScrollDown.Height + ScrollUp.Height)));
            this.ScrollBlock.RelativePosition = new Vector2(this.RelativePosition.X, this.ScrollUp.Height);
        }
        #endregion

        #region Override Method - ExecuteCommand(string command)
        public override void ExecuteCommand(string command)
        {
            // execute TextfieldObject custom command 'scrollUp'
            if (command.Equals("scrollUp"))
            {
                // Console.WriteLine(this.Name + " Command executed: " + command);
                if (_scrollTarget != null)
                    _scrollTarget.Scroll(IScrollClass.ScrollDirection.Up);
            }
            // execute TextfieldObject custom command 'scrollDown'
            else if (command.Equals("scrollDown"))
            {
                // Console.WriteLine(this.Name + " Command executed: " + command);
                if (_scrollTarget != null)
                    _scrollTarget.Scroll(IScrollClass.ScrollDirection.Down);
            }
        }
        #endregion


        #region IScrollbar Member - IScrollbar.Steps(int steps)
        void IScrollbar.ScrollSteps(int steps)
        {
            ScrollSteps = steps;
        }
        #endregion

        #region IScrollbar Member - IScrollbar.BlockOnStep(int step)
        void IScrollbar.BlockOnStep(int step)
        {
            float height = _bounds.Y - (ScrollUp.Height + ScrollDown.Height);
            float blockHeight = height / _scrollSteps;

            float y = 0;
            if (step > 0)
                y = blockHeight * (step);
            else y = 0;
            // y += blockHeight;

            ScrollBlock.Height = blockHeight;
            ScrollBlock.RelativePosition += new Vector2(0, y);
        }
        #endregion
    }
}